home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume13 / conf / part01 next >
Encoding:
Internet Message Format  |  1988-03-13  |  14.8 KB

  1. Subject:  v13i098:  Multi-user conferencing system, Part01/05
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Keith Gabryelski <ag@crash.cts.com>
  7. Posting-number: Volume 13, Issue 98
  8. Archive-name: conf/part01
  9.  
  10.  
  11. [  I did not repackage this into the more common 60K chunks.
  12.    Porting to V7 doesn't look too tough -- look for the three-arg
  13.    open() calls.  --r$ ]
  14.  
  15. Conf is a line oriented multi-user chat program designed to work on any
  16. SysV, BSD, or Xenix system.
  17.  
  18. Conf has several advantages over the standard write program supplied
  19. with most Unix and Xenix operating systems.
  20.  
  21.     o    Unlimited users conferencing at once.
  22.  
  23.     o    100 separate discussion lines.
  24.  
  25.     o    Public and private messages in addition to password
  26.          encrypted messages.
  27.  
  28.     o    Quick and efficient user interaction.
  29.  
  30.     o    User definable formats for messages.
  31.  
  32.     o    Intelligent message display algorithm.
  33. --------------------------------------------------------------------
  34. #! /bin/sh
  35. # This is a shell archive, meaning:
  36. # 1. Remove everything above the #! /bin/sh line.
  37. # 2. Save the resulting text in a file.
  38. # 3. Execute the file with /bin/sh (not csh) to create the files:
  39. #    MANIFEST
  40. #    Makefile
  41. #    conf.c
  42. #    conf.el
  43. export PATH; PATH=/bin:$PATH
  44. if test -f 'MANIFEST'
  45. then
  46.     echo shar: will not over-write existing file "'MANIFEST'"
  47. else
  48. cat << \SHAR_EOF > 'MANIFEST'
  49. A Manifest           Archived in
  50. ------------------------------------------------------------------------
  51. MANIFEST            1
  52. Makefile            1
  53. conf.c                1
  54. conf.el                1
  55. conf.h                2
  56. confalloc.c            2
  57. config.h            2
  58. confopts.c            2
  59. confprnt.c            3
  60. confrots.c            3
  61. confrw.c            3
  62. confsig.c            4
  63. confstr.c            4
  64. extern.h            4
  65. structs.h            4
  66. doc/READ_ME            5
  67. doc/conf.1            5
  68. doc/conf.txt            5
  69. doc/confhelp            5
  70. SHAR_EOF
  71. fi # end of overwriting check
  72. if test -f 'Makefile'
  73. then
  74.     echo shar: will not over-write existing file "'Makefile'"
  75. else
  76. cat << \SHAR_EOF > 'Makefile'
  77. SHELL=/bin/sh
  78. INSTALL= mv
  79. CFLAGS= -g
  80. SRCS= conf.c confrw.c confrots.c confopts.c confalloc.c confstr.c confprnt.c confsig.c
  81. OBJS= conf.o confrw.o confrots.o confopts.o confalloc.o confstr.o confprnt.o confsig.o
  82. HEDRS= conf.h config.h extern.h structs.h
  83. NEW= xconf
  84. NAME= conf
  85. LISP= conf.el
  86. MAKES= Makefile
  87. DOCDIR= doc
  88. CONFLIB= /usr/lib/conf
  89. BINDIR= /usr/local/bin
  90. LINT=lint
  91.  
  92. LIBS= -ltermlib
  93.  
  94. $(NEW): $(OBJS)
  95.     $(CC) $(CFLAGS) -o $(NEW) $(OBJS) $(LIBS)
  96.  
  97. clean:
  98.     rm -f *.o $(NEW) core
  99.  
  100. shar:
  101.     shar $(DOCDIR) $(MAKES) $(SRCS) $(HEDRS) $(LISP) > conf.shar
  102.  
  103. lint:
  104.     $(LINT) $(LIBS) $(SRCS)
  105.  
  106. install:
  107.     cp $(NEW) $(BINDIR)/$(NAME)
  108.     -mkdir $(CONFLIB)
  109.     cp $(DOCDIR)/confhelp $(CONFLIB)
  110.     -chmod 777 $(CONFLIB)
  111.     -chmod 644 $(CONFLIB)/* 
  112. SHAR_EOF
  113. fi # end of overwriting check
  114. if test -f 'conf.c'
  115. then
  116.     echo shar: will not over-write existing file "'conf.c'"
  117. else
  118. cat << \SHAR_EOF > 'conf.c'
  119. /*
  120.  *    conf - An interactive multi-user chat program.
  121.  *
  122.  *    conf Copyright (c) 1986, 1987 by Keith Gabryelski
  123.  *
  124.  *    Conf is quasi-public domain software; it may be used and copied
  125.  *    freely and may be modified to suit the indivuals needs as long
  126.  *    as:
  127.  *
  128.  *    [1] It is not sold.
  129.  *    [2] It is not made part of any licensed product.
  130.  *    [3] This header and others like it are not modified or removed.
  131.  *    [4] You allow others to use and copy without charge.
  132.  *    
  133.  *    without expressed written permission from the original
  134.  *    author (Keith Gabryelski).
  135.  *
  136.  *
  137.  */
  138.  
  139. #include "conf.h"
  140.  
  141. char *progname;        /* program name (argv[0]) */
  142. char *logname, *homedir;
  143. int log_rfd, log_wfd, usr_fd;
  144. long ourplace;
  145. FILE *rec_fp;
  146. int confing = FALSE;
  147.  
  148. char pubkey[MAXPASSWORDLEN], curkey[MAXPASSWORDLEN];
  149. char pubblock[MAXPASSWORDLEN*8], curblock[MAXPASSWORDLEN*8];
  150. char pubpass[MAXPASSWORDLEN], curpass[MAXPASSWORDLEN];
  151.  
  152. char replyname[MAXNAMELEN] = "";
  153. char replytty[MAXTTYLEN+1] = "";    /* there is a reason for the + 1
  154.                         although I have forgotten it
  155.                         right now, I'm sure it should
  156.                         be there.
  157.                      */
  158.  
  159. char *wrdata;
  160. unsigned wdlen=0;
  161.  
  162. struct cusrfil cuser, tuser;
  163. struct clogfil clog, tlog;
  164.  
  165. #ifdef    SYSV
  166. struct termio term, saveterm;
  167. #endif    SYSV
  168.  
  169. #ifdef    BSD
  170. struct tchars chrstr;
  171. struct sgttyb ktty;
  172. int ttyflags;
  173. #endif    BSD
  174.  
  175. char ichar = CTRL(C);            /* interrupt character */
  176. char qchar = CTRL(\\);            /* quit character */
  177.  
  178. jmp_buf env;
  179.  
  180. int columns = DEF_COLUMNS, lines = DEF_LINES;
  181. int banner = TRUE, seeme = TRUE, informe = FALSE, warncrypt = TRUE;
  182. int autowho = FALSE, lineinput = FALSE, beep = FALSE, askdump = TRUE;
  183. int expand8bit = TRUE, expandctrl = TRUE;
  184.  
  185. char *cls, *pager, *shell, *normform, *lineform, *shoutform, *sendform;
  186. char *informform, *recfile;
  187.  
  188. my_int()
  189. {
  190.     longjmp(env, 1);
  191. }
  192.  
  193. main(argc, argv)
  194. int argc;
  195. char *argv[];
  196. {
  197.     char *ptr, *word, *line;
  198.     int num, x, old_umask;
  199.     struct passwd *pt;
  200.  
  201.     /* set up some pointers to interesting stuff */
  202.     wrdata = mymalloc(wdlen = PAGESIZ);
  203.  
  204.     progname = *argv++; argc--;
  205.     cuser.cu_line = 1;
  206.     cuser.cu_flags = USER_ON;
  207.     cuser.cu_procid = getpid();
  208.  
  209.     pt = getpwuid(getuid());
  210.  
  211.     if ((ptr = getlogin()) == NULL)
  212.     if ((ptr = pt->pw_name) == NULL)
  213.         ptr = "???";        /* can't figure this guy out */
  214.  
  215.     logname = mymalloc((unsigned)(strlen(ptr)+1));
  216.     (void) strcpy(logname, ptr);
  217.  
  218.     (void) strcpy(cuser.cu_cname, ptr);
  219.     (void) strcpy(cuser.cu_tty, ((ptr= strrchr(ttyname(0), '/')) ? ptr+1 : "tty??"));
  220.  
  221.     homedir = mymalloc((unsigned)(strlen(pt->pw_dir)+1));
  222.     (void) strcpy(homedir, pt->pw_dir);
  223.  
  224.     zbuf(pubkey, MAXPASSWORDLEN);
  225.     (void)strncpy(pubkey, DEF_KEY, MAXPASSWORDLEN);
  226.     zbuf(curkey, MAXPASSWORDLEN);
  227.     (void)strncpy(curkey, DEF_KEY, MAXPASSWORDLEN);
  228.  
  229.     cls = mymalloc((unsigned)(strlen(DEF_CLS)+1));
  230.     (void) strcpy(cls, DEF_CLS);
  231.  
  232.     normform = mymalloc((unsigned)(strlen(DEF_FORM_NORM)+1));
  233.     (void) strcpy(normform, DEF_FORM_NORM);
  234.  
  235.     sendform = mymalloc((unsigned)(strlen(DEF_FORM_SEND)+1));
  236.     (void) strcpy(sendform, DEF_FORM_SEND);
  237.  
  238.     shoutform = mymalloc((unsigned)(strlen(DEF_FORM_SHOUT)+1));
  239.     (void) strcpy(shoutform, DEF_FORM_SHOUT);
  240.  
  241.     informform = mymalloc((unsigned)(strlen(DEF_FORM_INFORM)+1));
  242.     (void) strcpy(informform, DEF_FORM_INFORM);
  243.  
  244.     lineform = mymalloc((unsigned)(strlen(DEF_FORM_LINE)+1));
  245.     (void) strcpy(lineform, DEF_FORM_LINE);
  246.  
  247.     pager = mymalloc((unsigned)(strlen(DEF_PAGER)+1));
  248.     (void) strcpy(pager, DEF_PAGER);
  249.  
  250.     shell = mymalloc((unsigned)(strlen(DEF_SHELL)+1));
  251.     (void) strcpy(shell, DEF_SHELL);
  252.  
  253.     recfile = mymalloc((unsigned)(strlen(DEF_RECFILE)+1));
  254.     (void) strcpy(recfile, DEF_RECFILE);
  255.  
  256.     gettcap();            /* get termcap stuff */
  257.     getrc();            /* get some defaults from rc file */
  258.     getopts();            /* get some defaults from environment */
  259.  
  260.     while (word = *argv++, argc--)
  261.     {
  262.     if (*word == '-')
  263.     {
  264.        word++;
  265.        while (*word != '\0')
  266.        {
  267.            switch(*word++)
  268.            {
  269.             case 'l':
  270.             if (*word == '\0')
  271.             {
  272.                 if (!argc)
  273.                 {
  274.                 (void)printf("%s: -l switch specified without a conference line number\n",
  275.                     progname);
  276.                 usage();
  277.                 }
  278.                 word = *argv++; --argc;
  279.             }
  280.  
  281.             num = atoi(word);
  282.             if ((num < 1) || (num > MAXCONFLINES))
  283.             {
  284.                 (void)printf("%s: invalid conference line number: %d\n",
  285.                 progname, num);
  286.                 usage();
  287.             }
  288.             cuser.cu_line = num;
  289.             *word = '\0';
  290.             break;
  291.  
  292.             case 's':
  293.             if (*word == '\0')
  294.             {
  295.                 if (!argc)
  296.                 {
  297.                 (void)fprintf(stderr, "%s: -s specified without a parameter\n", progname);
  298.                 usage();
  299.                 }
  300.                 word = *argv++; --argc;
  301.             }
  302.  
  303.             if ((x = setopts(parsestr(word, strlen(word), NEXTWORD))) != FOUNDOPT)
  304.             {
  305.                 char *errmess;
  306.  
  307.                 if (x == AMBIGUOUS)
  308.                 errmess = "Ambiguous";
  309.                 else
  310.                 errmess = "Invalid";
  311.                 
  312.                 (void)fprintf(stderr, "%s: %s -s parameter: %s\n",
  313.                     progname, errmess, word);
  314.                 usage();
  315.             }
  316.             *word = '\0';
  317.             break;
  318.  
  319.             case 'w':
  320.             (void) do_who(0);
  321.             (void) exit(0);
  322.  
  323.             default:
  324.             (void)fprintf(stderr, "%s: invalid parameter '%c'\n",
  325.                 progname, *(word-1));
  326.             usage();
  327.         }
  328.         }
  329.     }
  330.     else
  331.         (void) do_ring(word);
  332.     }
  333.  
  334.     /* by this point, all parameters/options have been parsed */
  335.  
  336.     confing = TRUE;
  337.  
  338.     makepass(pubkey, pubblock, pubpass);
  339.     makepass(curkey, curblock, curpass);
  340.  
  341.     clog.f_line = cuser.cu_line;
  342.     clog.f_usrlen = strlen(cuser.cu_cname) + 1;
  343.     clog.f_ttylen = strlen(cuser.cu_tty) + 1;
  344.  
  345.     old_umask = umask(0);
  346.  
  347.     if ((usr_fd = open(CONFUSERS, O_RDWR|O_CREAT, FILEMASK)) < 0)
  348.     {
  349.     (void)fprintf(stderr, "%s: couldn't open %s (%s)\n", progname,
  350.         CONFUSERS, puterr(errno));
  351.     (void) exit(-1);
  352.     }
  353.  
  354.     (void)lseek(usr_fd, 0L, 0);
  355.  
  356. #ifdef    SYSV
  357.     lockf(usr_fd, F_LOCK, 0L);    /* lock user file */
  358. #endif    SYSV
  359.  
  360. #ifdef    BSD
  361.     flock(usr_fd, LOCK_EX);
  362. #endif    BSD
  363.  
  364.     ourplace = lseek(usr_fd, 0L, 1);
  365.     while (read(usr_fd, (char *)&tuser, sizeof(struct cusrfil)) ==
  366.     sizeof(struct cusrfil))
  367.     if (tuser.cu_flags == USER_OFF)
  368.         break;
  369.     else
  370.         ourplace = lseek(usr_fd, 0L, 1);
  371.  
  372.     (void)lseek(usr_fd, ourplace, 0);
  373.  
  374.     write(usr_fd, (char *)&cuser, sizeof(struct cusrfil));
  375.  
  376. #ifdef    SYSV
  377.     (void)lseek(usr_fd, 0L, 0);
  378.     lockf(usr_fd, F_ULOCK, 0L);
  379. #endif    SYSV
  380.  
  381. #ifdef    BSD
  382.     flock(usr_fd, LOCK_UN);
  383. #endif    BSD
  384.  
  385.     if ((log_wfd = open(CONFLOG, O_WRONLY|O_CREAT|O_APPEND, FILEMASK)) < 0)
  386.     {
  387.     (void)fprintf(stderr,"%s: couldn't create/open %s for writing(%s)\n",
  388.         progname, CONFLOG, puterr(errno));
  389.     (void) exit(-1);
  390.     }
  391.  
  392.     (void) umask(old_umask);
  393.  
  394.     if ((log_rfd = open(CONFLOG, O_RDONLY)) < 0)
  395.     {
  396.     (void)fprintf(stderr,"%s: couldn't open %s for reading (%s)\n",
  397.         progname, CONFLOG, puterr(errno));
  398.     (void) exit(-1);
  399.     }
  400.  
  401.     /* any fatal errors pass this point must do a nice_exit(status) */
  402.  
  403.     (void)lseek(log_rfd, 0L, 2);
  404.     write_log(INFORM, "Login", (char *)NULL, 0, (unsigned)strlen("Login"));
  405.  
  406. #ifdef    SYSV
  407.     (void) ioctl(0, TCGETA, &term);
  408.     saveterm=term;
  409.  
  410.     if (!(term.c_lflag&ECHO))
  411.     lineinput = TRUE;
  412.  
  413.     ichar = term.c_cc[VINTR];
  414.     qchar = term.c_cc[VQUIT];
  415.  
  416.     term.c_iflag &= ~(ICRNL);
  417.     term.c_lflag &= ~(ICANON|ECHO);
  418.     term.c_cc[VEOF] = 1;
  419.     term.c_cc[VEOL] = 0;
  420.     (void) ioctl(0, TCSETAW, &term);
  421. #endif    SYSV
  422.  
  423. #ifdef    BSD
  424.     gtty(0, &ktty);
  425.     ttyflags = ktty.sg_flags;
  426.  
  427.     if (!(ttyflags&ECHO))
  428.     lineinput = TRUE;
  429.  
  430.     ktty.sg_flags |= CBREAK;
  431.     ktty.sg_flags &= ~ECHO;
  432.     stty(0, &ktty);
  433.  
  434.     (void) ioctl(0, TIOCGETC, &chrstr);
  435.     ichar = chrstr.t_intrc;
  436.     qchar = chrstr.t_quitc;
  437. #endif    BSD
  438.  
  439.     (void)signal(SIGINT, SIG_IGN);
  440.     (void)signal(SIGQUIT, fatal);
  441.     (void)signal(SIGHUP, nice_exit);
  442.     (void)signal(SIGTERM, nice_exit);
  443.     (void)signal(SIGILL, fatal);
  444.     (void)signal(SIGTRAP, fatal);
  445.     (void)signal(SIGIOT, fatal);
  446.     (void)signal(SIGEMT, fatal);
  447.     (void)signal(SIGFPE, fatal);
  448.     (void)signal(SIGBUS, fatal);
  449.     (void)signal(SIGSEGV, fatal);
  450.     (void)signal(SIGSYS, fatal);
  451.     (void)signal(SIGPIPE, fatal);
  452.  
  453.     if (banner)
  454.     (void) version(FALSE);
  455.  
  456.     if (autowho)
  457.     {
  458.     (void) printf("Currently on %s:\n\n", progname);
  459.     (void) do_who(0);
  460.     (void) putchar('\n');
  461.     }
  462.  
  463.     (void)printf("login user %s (%s) on conference line %d\n",
  464.     cuser.cu_cname, cuser.cu_tty, cuser.cu_line);
  465.  
  466.     if (setjmp(env))
  467.     {
  468.     (void)signal(SIGINT, my_int);
  469.     dispchar(ichar, stdout, NOVIS);
  470.     (void)putchar('\n');
  471.     (void)lseek(log_rfd, 0L, 2);
  472.     }
  473.     else
  474.     (void)signal(SIGINT, my_int);
  475.  
  476.     forever
  477.     {
  478.     read_log();
  479.  
  480.     line = getline();
  481.     (void)signal(SIGINT, my_int);
  482.     if (line != NULL)
  483.     {
  484.         if ((*line == ':') && (*(line+1) != ':'))
  485.         {
  486.             if (*(line+1) == '!')
  487.             keep_shell(line+2);
  488.         else
  489.         {
  490.             --linelen;
  491.             (void) intpret(line+1);
  492.         }
  493.         }
  494.         else
  495.         {
  496.         if (*line == ':')
  497.             write_log(NORMAL, line+1, (char *)NULL, 0, linelen-1);
  498.         else
  499.             write_log(NORMAL, line, (char *)NULL, 0, linelen);
  500.         }
  501.         free(line);
  502.     }
  503.     }
  504. }
  505.  
  506. nice_exit(status)
  507. int status;
  508. {
  509.     make_nice(TRUE);
  510.  
  511.     (void)signal(SIGALRM, SIG_DFL);
  512.     (void)signal(SIGINT, SIG_DFL);
  513.     (void)signal(SIGQUIT, SIG_DFL);
  514.     (void)signal(SIGHUP, SIG_DFL);
  515.     (void)signal(SIGTERM, SIG_DFL);
  516.     (void)signal(SIGILL, SIG_DFL);
  517.     (void)signal(SIGTRAP, SIG_DFL);
  518.     (void)signal(SIGIOT, SIG_DFL);
  519.     (void)signal(SIGEMT, SIG_DFL);
  520.     (void)signal(SIGFPE, SIG_DFL);
  521.     (void)signal(SIGBUS, SIG_DFL);
  522.     (void)signal(SIGSEGV, SIG_DFL);
  523.     (void)signal(SIGSYS, SIG_DFL);
  524.     (void)signal(SIGPIPE, SIG_DFL);
  525.  
  526.     (void) exit(status);
  527. }
  528.  
  529. make_nice(status)
  530. int status;
  531. {
  532.     int c, rotten_egg;        /* last one out ... */
  533.  
  534.     (void)alarm(0);
  535.  
  536.     if (status)
  537.     write_log(INFORM,"Logout",(char *)NULL,0, (unsigned)strlen("Logout"));
  538.  
  539.     if (cuser.cu_flags&USER_RECORD)
  540.     (void)fclose(rec_fp);
  541.  
  542.     cuser.cu_flags = USER_OFF;
  543.     write_usr();
  544.  
  545.     (void)lseek(usr_fd, 0L, 0);
  546.  
  547. #ifdef    SYSV
  548.     lockf(usr_fd, F_LOCK, 0L);    /* lock user file */
  549. #endif    SYSV
  550.  
  551. #ifdef    BSD
  552.     flock(usr_fd, LOCK_EX);
  553. #endif    BSD
  554.  
  555.     rotten_egg = TRUE;
  556.     while (read(usr_fd, (char *)&tuser, sizeof(struct cusrfil)) ==
  557.     sizeof(struct cusrfil))
  558.     if (tuser.cu_flags != USER_OFF)
  559.     {
  560.         c = kill(tuser.cu_procid, 0);
  561.         if ((!c) || ((c < 0) && (errno != ESRCH)))
  562.         rotten_egg = FALSE;
  563.     }
  564.  
  565.     if (rotten_egg)
  566.     {
  567.     if (unlink(CONFLOG) < 0)
  568.         (void)printf("%s: couldn't remove %s (%s)\n", progname, CONFLOG,
  569.         puterr(errno));
  570.  
  571.     if (unlink(CONFUSERS) < 0)
  572.         (void)printf("%s: couldn't remove %s (%s)\n", progname, CONFUSERS,
  573.         puterr(errno));
  574.     }
  575.  
  576. #ifdef    SYSV
  577.     (void)lseek(usr_fd, 0L, 0);
  578.     lockf(usr_fd, F_ULOCK, 0L);
  579. #endif    SYSV
  580.  
  581. #ifdef    BSD
  582.     flock(usr_fd, LOCK_UN);
  583. #endif    BSD
  584.  
  585.     (void)close(usr_fd);
  586.     (void)close(log_rfd);
  587.     (void)close(log_wfd);
  588.  
  589. #ifdef    SYSV
  590.     (void) ioctl(0, TCSETAW, &saveterm);
  591. #endif    SYSV
  592.  
  593. #ifdef    BSD
  594.     ktty.sg_flags = ttyflags;
  595.     stty(0, &ktty);
  596. #endif    BSD
  597. }
  598.  
  599. usage()
  600. {
  601.     (void)fprintf(stderr, "usage: %s [-w][-s switchname][-l line-number]\n",
  602.         progname);
  603.     (void) exit(-1);
  604. }
  605. SHAR_EOF
  606. fi # end of overwriting check
  607. if test -f 'conf.el'
  608. then
  609.     echo shar: will not over-write existing file "'conf.el'"
  610. else
  611. cat << \SHAR_EOF > 'conf.el'
  612. ;; Run conf(1) as asynchronous inferior of Emacs.
  613. ;; provided by Michael Ditto (ford@kenobi.cts.com)
  614. ;; This file is not part of GNU Emacs.
  615.  
  616. (defvar conf-process nil "The process of conf.")
  617.  
  618. (defun conference (switches)
  619.   "Conference with other users."
  620.   (interactive "sArgs to conference (switches): ")
  621.  
  622.   (require 'shell)
  623.  
  624.   (let ((buffer (get-buffer-create "*conference*")))
  625.     (switch-to-buffer buffer)
  626.  
  627.     (if (get-buffer-process buffer)
  628.     (error "A conference process is already running"))
  629.  
  630.     (setq conf-process
  631.       (start-process "conf" buffer
  632.              "/bin/sh" "-c" (format "conf %s" switches))))
  633.  
  634.   (shell-mode)
  635.   (turn-on-auto-fill)
  636.   (setq mode-name "Conference")
  637.   (set-marker (process-mark conf-process) (point-max))
  638.   (set-process-filter conf-process 'conf-filter))
  639.  
  640. (defun conf-filter (process string)
  641.   (save-excursion
  642.     (set-buffer (process-buffer process))
  643.     (goto-char (process-mark process))
  644.     (let ((start-line (point)))
  645.       (insert-before-markers string)
  646.       ;;    (fill-region start-line (point))
  647.       )
  648.  
  649.     (if (get-buffer-window (process-buffer process))
  650.     nil
  651.       (beep t))))
  652. SHAR_EOF
  653. fi # end of overwriting check
  654. #    End of shell archive
  655. exit 0
  656.  
  657.